<template>
  <el-form label-width="120px">
    <el-form-item label="SPU名称">
      <el-input placeholder="请输入SPU名称" v-model="spuModel.spuName" />
    </el-form-item>
    <el-form-item label="SPU品牌">
      <el-select placeholder="请输入SPU品牌" v-model="spuModel.tmId">
        <el-option
          v-for="item in trademarkList"
          :index="item.id"
          :label="item.tmName"
          :value="item.id"
        />
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述 ">
      <el-input
        type="textarea"
        placeholder="请输入SPU描述"
        v-model="spuModel.description"
      />
    </el-form-item>
    <el-form-item label="SPU图标">
      <el-upload
        v-model:file-list="imageList"
        action="/api/admin/product/fileUpload"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :before-upload="handleUpload"
      >
        <el-icon>
          <Plus />
        </el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img
          w-full
          :src="dialogImageUrl"
          alt="Preview Image"
          style="width: 100%; height: 100%"
        />
      </el-dialog>
    </el-form-item>
    <el-form-item label="SPU销售属性">
      <el-select
        v-model="addSaleAttrName"
        :placeholder="
          unSelectSaleAttr.length > 0
            ? `还有${unSelectSaleAttr.length}个未选择`
            : '无'
        "
      >
        <el-option
          v-for="item in unSelectSaleAttr"
          :label="item.name"
          :value="`${item.id}:${item.name}`"
          :key="item.id"
        />
      </el-select>
      <el-button
        type="primary"
        style="margin: 0px 10px"
        icon="plus"
        :disabled="addSaleAttrName ? false : true"
        @click="addSaleAttr"
      >
        添加属性值
      </el-button>
    </el-form-item>
    <el-form-item>
      <el-table border :data="spuSaleAttrList">
        <el-table-column label="序号" type="index" width="80" />
        <el-table-column label="销售属性名称" prop="saleAttrName" width="180" />
        <el-table-column label="销售属性值">
          <template #="{ row, $index }">
            <el-tag
              v-for="(tag, index) in row.spuSaleAttrValueList"
              :key="tag.id"
              style="margin: 0px 5px"
              closable
              :disable-transitions="false"
              @close="row.spuSaleAttrValueList.splice(index, 1)"
            >
              {{ tag.saleAttrValueName }}
            </el-tag>
            <el-input
              v-if="row.isEdit"
              v-model="row.saleAttrValueName"
              size="small"
              @keyup.enter="handleInputConfirm(row)"
              @blur="handleInputConfirm(row)"
              style="width: 200px"
            />
            <el-button
              v-else
              class="button-new-tag ml-1"
              size="small"
              @click="showInput(row)"
            >
              + New Tag
            </el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="100">
          <template #="{ row, $index }">
            <el-button
              type="primary"
              size="small"
              icon="Delete"
              @click="spuSaleAttrList.splice($index, 1)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="SaveOrUpdate">保存</el-button>
      <el-button type="primary" @click="cancel">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
//接收父组件自定义事件
let $emit = defineEmits(['changeScence'])
import { GetAllTrademark } from '@/api/product/trademark'
import {
  GetSpuImageList,
  GetSpuSaleAttrList,
  GetBaseSaleAttrList,
  SaveOrUpdateSpu,
} from '@/api/product/spu'

//引入类型
import type {
  SpuRecord,
  SpuImageData,
  SaleAttrResponseData,
  SaleAttrData,
} from '@/api/product/spu/type'
import type { Trademark } from '@/api/product/trademark/type'
import { ElMessage, ElInput } from 'element-plus'

//接收spu数据
let spuModel = ref<SpuRecord>({
  spuName: '',
  description: '',
  category3Id: 0,
  tmId: 0,
  spuSaleAttrList: [],
  spuImageList: [],
})

const showInput = (row: SaleAttrResponseData) => {
  row.isEdit = true
}

//属性值添加完成后回调
const handleInputConfirm = (row: SaleAttrResponseData) => {
  //从SaleAttrResponseData获取值
  let { baseSaleAttrId, saleAttrName, saleAttrValueName } = row

  //判断属性值不能为空
  if ((saleAttrValueName as string)?.trim() == '') {
    ElMessage.error('属性值名称不能为空')
    return
  }
  //判断是否重复
  let repeat = row.spuSaleAttrValueList.find((item) => {
    return item.saleAttrValueName == saleAttrValueName
  })

  if (repeat) {
    ElMessage.error('属性值名称不能重复')
    return
  }

  //添加到属性列表中
  const attrModel = {
    baseSaleAttrId,
    saleAttrValueName,
    saleAttrName,
  }
  row.spuSaleAttrValueList.push(attrModel)

  //切换为显示模式
  row.isEdit = false
  row.saleAttrValueName = ''
}
//接收全部品牌数据
let trademarkList = ref<Trademark[]>([])
//接收spu下所有图像数据
let imageList = ref<SpuImageData[]>([])
//接收spu下的销售属性
let spuSaleAttrList = ref<SaleAttrResponseData[]>([])
//接收所有的销售属性
let baseSaleAttrList = ref<SaleAttrData[]>([])
//取消按钮回调
const cancel = () => {
  addSaleAttrName.value = ''
  $emit('changeScence', 0)
}
//初始化数据回调方法
const initSpuData = async (data: SpuRecord) => {
  spuModel.value = data
  //获取全部品牌数据
  let trademarkResponse = await GetAllTrademark()
  if (trademarkResponse.code == 200) {
    trademarkList.value = trademarkResponse.data
  }
  //获取spu下的图像数据
  let imagesResponse = await GetSpuImageList(data.id as number)
  if (imagesResponse.code == 200) {
    imageList.value = imagesResponse.data.map((item) => {
      return {
        name: item.imgName,
        url: item.imgUrl,
      }
    })
  }
  //获取spu下所有的销售属性
  let spuSaleAttrResponse = await GetSpuSaleAttrList(data.id as number)
  if (spuSaleAttrResponse.code == 200) {
    spuSaleAttrList.value = spuSaleAttrResponse.data
  }
  //获取所有的销售属性
  let baseSaleAttrResponse = await GetBaseSaleAttrList()
  if (baseSaleAttrResponse.code == 200) {
    baseSaleAttrList.value = baseSaleAttrResponse.data
  }
}

//照片墙弹出窗显示
let dialogVisible = ref<boolean>(false)
//照片墙中图片放大后的地址
let dialogImageUrl = ref<string>()
//点击放大后的回调函数
const handlePictureCardPreview = (uploadFile: SpuImageData) => {
  dialogVisible.value = true
  dialogImageUrl.value = uploadFile.url
}
//点击删除的回调
const handleRemove = () => {}

//上传成功前的函数钩子
const handleUpload = (rawFile: any) => {
  if (
    rawFile.type == 'image/png' ||
    rawFile.type == 'image/jpeg' ||
    rawFile.type == 'image/gif'
  ) {
    if (rawFile.size / 1024 / 1024 < 3) {
      return true
    } else {
      ElMessage.error('上传的文件大小不能大于3M')
      return false
    }
  } else {
    ElMessage.error('上传的文件格式必须是图片')
    return false
  }
}
//收集获取新添加的属性
let addSaleAttrName = ref<string>('')
//点击添加属性按钮回调
const addSaleAttr = () => {
  let [baseSaleAttrId, saleAttrName] = addSaleAttrName.value.split(':')

  let newSaleAttr: SaleAttrResponseData = {
    baseSaleAttrId,
    saleAttrName,
    spuSaleAttrValueList: [],
  }

  spuSaleAttrList.value.push(newSaleAttr)

  addSaleAttrName.value = ''
}
//通过计算属性获取还有多少个属性没选择
let unSelectSaleAttr = computed(() => {
  let unSelectArrt = baseSaleAttrList.value.filter((item) => {
    return spuSaleAttrList.value.every((item1) => {
      return item.id != item1.baseSaleAttrId
    })
  })
  return unSelectArrt
})

const SaveOrUpdate = async () => {
  //组装照片墙数据
  spuModel.value.spuImageList = imageList.value.map((item: any) => {
    return {
      imgName: item.name,
      imgUrl: (item.response && item.response.data) || item.url,
    }
  })
  //组装属性列表数据
  spuModel.value.spuSaleAttrList = spuSaleAttrList.value

  //将数据发送服务器
  let responseResult = await SaveOrUpdateSpu(spuModel.value)

  if (responseResult.code == 200) {
    ElMessage.success(`${spuModel.value.id ? '更新' : '添加'}成功`)
    //返回父窗口
    $emit('changeScence', 0)
  } else {
    ElMessage.error(
      `${spuModel.value.id ? '更新' : '添加'}失败，${responseResult.message}`,
    )
  }
}
//对外暴露组件中的方法
defineExpose({ initSpuData })
</script>

<style scoped></style>
